﻿using LPLS.Commons.DynamicOP;
using LPLS.Commons.Exten;
using LPLS.Commons.LogOP;
using LPLS.DBEntities.ConfigModels.DataCollectionConfigModule.DataCollectionType.PLC;
using Masuit.Tools.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RulesEngine.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LPLS.RuleEngineBaseCommon
{
    /// <summary>
    /// 基础的的工作流
    /// </summary>
    public abstract class RuleEngineBaseWorkFlow<T> where T : Enum
    {
        public RuleEngineBaseWorkFlow(string jsonname, Guid deviceID, Guid compentID, List<PLCVarPropertyConfig> pLCVarList)
        {
            PLCVarList = new List<PLCVarPropertyConfig>();
            JsonPath = jsonname;
            Workflows = GetRuleWorkFlow();
            DeviceID = deviceID;
            CompentID = compentID;
            PLCVarList=pLCVarList;
        }

   public List<PLCVarPropertyConfig> PLCVarList { get; set; } 
        public Guid DeviceID { get; set; }

        public Guid CompentID { get; set; }
        public string JsonPath { get; set; } = null;

        public string WorkflowName { get; set; } = null;
        /// <summary>
        /// 保存工作流到json
        /// </summary>
        /// <param name="workflows"></param>
        /// <param name="jsonpath"></param>

        public void CreatRuleJson(List<Workflow> workflows)
        {
            string json = JsonConvert.SerializeObject(workflows, Formatting.Indented);
            File.WriteAllText(JsonPath, json);
        }

        /// <summary>
        /// 通过json获取 workflow集合
        /// </summary>
        /// <param name="jsonpath"></param>
        /// <returns></returns>
        public List<Workflow> GetRuleWorkFlow()
        {
            if (string.IsNullOrEmpty(JsonPath))
            {

                LogManager.Info($"{nameof(GetRuleWorkFlow)}函数 获取工作流失败  json的路径名称（JsonPath）  为空");
             
                return new List<Workflow>();
            }
            var jsonstring = File.ReadAllText(JsonPath);
            if (string.IsNullOrEmpty(jsonstring))
            {
                LogManager.Info($"{nameof(GetRuleWorkFlow)}函数 获取工作流失败  Json里没东西为空");


             
                return new List<Workflow>();
            }
            JArray workflows = JArray.Parse(jsonstring);
            string workflowName = workflows?[0]?["WorkflowName"]?.ToString();

            this.WorkflowName = workflowName;
            if (string.IsNullOrEmpty(workflowName))
            {
                LogManager.Info($"{nameof(GetRuleWorkFlow)}函数 获取工作流失败  工作流名称为空");
            
                return new List<Workflow>();
            }
            var data = JsonConvert.DeserializeObject<List<Workflow>>(jsonstring);
            if (data != null)
            {
                return data;


            }
            else
            {
                LogManager.Info($"{nameof(GetRuleWorkFlow)}函数 获取工作流失败  该工作流为空");            
                return new List<Workflow>();
            }
        }


        public List<Workflow> Workflows { get; set; } = new List<Workflow>();


        /// <summary>
        /// 数据采集上来之后进行条件规则筛选  并返回符合的规则的枚举结果值    注意  规则冲突时只会返回第一条符合的规则
        /// </summary>
        /// <typeparam name="T"> 枚举类型 是规则删选后的枚举结果值 </typeparam>
        /// <param name="input">数据采集上来的数据</param>
        /// <param name="workflowName"> 工作流名称</param>
        /// <param name="JsonPath">json文件名称</param>
        /// <returns></returns>
        public T? ExecuteRules<T>(Dictionary<string, object> input) where T : struct, Enum
        {

            var inputDynamic = input.ToStronglyTypedDynamic();
            // 转换为动态对象
            var expando = new ExpandoObject();
            var expandoDict = (IDictionary<string, object>)expando;
            if (inputDynamic is IDictionary<string, object> inputDict)
            {
                foreach (var kvp in inputDict)
                {
                    expandoDict[kvp.Key] = kvp.Value;
                }
            }
            else
            {
                // 备选方案：处理非字典动态对象
                foreach (var propName in DynamicHelper.GetPropertyNames(inputDynamic))
                {
                    expandoDict[propName] = DynamicHelper.GetPropertyValue(inputDynamic, propName);
                }
            }
            var fileWorkflow = Workflows;
            if (fileWorkflow == null || fileWorkflow.Count == 0)
            {
                LogHelper.Information($"没有找到{this.WorkflowName}工作流");

                return null;
            }
            var bre = new RulesEngine.RulesEngine(fileWorkflow.ToArray());
            var resultList = bre.ExecuteAllRulesAsync(this.WorkflowName, expando).Result;
            var firstSuccess = resultList.FirstOrDefault(r => r.IsSuccess);
            if (firstSuccess != null)
            {
                // 从 Rule 属性中获取 SuccessEvent
                var successEvent = firstSuccess.Rule?.SuccessEvent;
                if (!string.IsNullOrEmpty(successEvent)  )
                {

                    var res = Enum.TryParse(successEvent, true, out T result);
                    return result;
                }
            }
            return null;
        }


        /// <summary>
        /// 通过
        /// </summary>
        /// <param name="t"></param>
        public abstract void HandleRuleResult(T t);
    }

}
